import 'package:flutter/material.dart';
import 'package:flutter_demo/pages/page_with_title.dart';

import '../../conf/m3.dart';
import '../../widgets/app_widgets.dart';

class ListItemAnimationPage extends PageWithTitle {
  const ListItemAnimationPage() : super("列表项动画(AnimatedList)");

  @override
  List<Widget> buildContentWidgets(BuildContext context) {
    return const [
      PrimaryTitle("简介"),
      BodyText("普通的列表不具备item动画，但Flutter封装了一些支持动画的列表组件"),
      AppSpacer.large,
      _AnimatedListExample(),
      AppSpacer.mini,
      UlItem("AnimatedList"),
      BodyText("动画列表，可以自定义列表item添加与移除时的动画"),
      LabelText(
          "- key，虽是可选实则必传，通过设置一个GlobalKey来接收这个组件创建的state，我们在需要修改数据时，通过获取它的state对象来通知它item插入与移除"),
      LabelText(
          "- itemBuilder，item构建器，会提供context、index、animation让开发者创建item widget。其中animation是一个动画对象，在列表内部执行添加动画时，animation会通过监听让你的item执行一个0到1的动画。"),
      LabelText("- initialItemCount，初始化item数量，构建时不会触发动画"),
      LabelText("- scrollDirection，设置布局方向，默认纵向"),
      LabelText("- reverse，反转列表"),
      LabelText("- shrinkWrap，列表自适应内容高度"),
      LabelText("- padding，内边距"),
      OlItem(1, "插入item"),
      LabelText("- insertAllItems，在index批量插入多个item，不设置duration则采用默认的300毫秒"),
      LabelText("- insertItem，在index批量插入item"),
      OlItem(2, "移除item，"),
      LabelText("- removeAllItems，移除所有item"),
      LabelText(
          "- removeItem，移除index位置的item，builder提供一个从1变化到0的animation，开发者需要构建一个具有移除动画效果的item组件"),
      AppSpacer.large,
      _AnimatedGridExample(),
    ];
  }
}

class _AnimatedListExample extends StatefulWidget {
  const _AnimatedListExample();

  @override
  State<StatefulWidget> createState() {
    return _AnimatedListExampleState();
  }
}

class _AnimatedListExampleState extends State<_AnimatedListExample> {
  final globalListKey = GlobalKey<AnimatedListState>();
  var _nameIndex = 0;
  final listData = [];

  @override
  void initState() {
    super.initState();
    _firstShow();
  }

  void _firstShow() async {
    for (int i = 0; i < 3; i++) {
      await Future.delayed(const Duration(milliseconds: 300));
      listData.add("item ${_nameIndex++}");
      globalListKey.currentState?.insertItem(listData.length - 1);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        color: Theme.of(context).colorScheme.surfaceContainer,
        borderRadius: M3.connerRadiusMedium,
      ),
      child: AnimatedList(
        key: globalListKey,
        //使列表可以自适应大小，等同于一个LinearLayout那样去用
        shrinkWrap: true,
        padding: const EdgeInsetsDirectional.all(16),
        initialItemCount: listData.length + 1,
        itemBuilder: (context, index, animation) {
          if (index < listData.length) {
            return SizeTransition(
              sizeFactor: animation,
              child: FadeTransition(
                opacity: animation,
                child: _buildItem(context, index, listData[index], animation),
              ),
            );
          } else {
            return FilledButton(
                onPressed: () {
                  listData.add("item ${_nameIndex++}");
                  globalListKey.currentState?.insertItem(listData.length - 1);
                },
                child: const Text("add item"));
          }
        },
      ),
    );
  }

  Widget _buildItem(BuildContext context, int? index, String item,
      Animation<double> animation) {
    final colorScheme = Theme.of(context).colorScheme;
    return InkWell(
      onTap: () {
        if (index != null) {
          final removedItem = listData.removeAt(index);
          globalListKey.currentState?.removeItem(index, (context, animation) {
            return SlideTransition(
                position: Tween(
                  begin: const Offset(1, 0),
                  end: const Offset(0, 0),
                ).animate(animation),
                child: _buildItem(context, null, removedItem, animation));
          });
        }
      },
      child: Container(
        margin: const EdgeInsetsDirectional.all(M3.paddingS / 2),
        width: double.infinity,
        height: 36,
        decoration: BoxDecoration(
          color: colorScheme.primary,
          borderRadius: M3.connerRadiusMedium,
        ),
        padding: const EdgeInsetsDirectional.symmetric(horizontal: M3.paddingM),
        alignment: AlignmentDirectional.center,
        child: Text(
          item,
          style: TextStyle(color: colorScheme.onPrimary),
        ),
      ),
    );
  }
}

class _AnimatedGridExample extends StatefulWidget {
  const _AnimatedGridExample();

  @override
  State<StatefulWidget> createState() {
    return _AnimatedGridExampleState();
  }
}

class _AnimatedGridExampleState extends State<_AnimatedGridExample> {
  final globalListKey = GlobalKey<AnimatedGridState>();
  var _nameIndex = 0;
  final listData = [];

  @override
  void initState() {
    super.initState();
    _firstShow();
  }

  void _firstShow() async {
    for (int i = 0; i < 3; i++) {
      await Future.delayed(const Duration(milliseconds: 300));
      listData.add("item ${_nameIndex++}");
      globalListKey.currentState?.insertItem(listData.length - 1);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Container(
          height: 200,
          decoration: BoxDecoration(
            color: Theme.of(context).colorScheme.surfaceContainer,
            borderRadius: M3.connerRadiusMedium,
          ),
          child: AnimatedGrid(
            key: globalListKey,
            padding: const EdgeInsetsDirectional.all(16),
            initialItemCount: listData.length,
            gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 4,
              mainAxisSpacing: M3.paddingS, //主轴间距
              crossAxisSpacing: M3.paddingS,
              childAspectRatio: 1,
            ),
            itemBuilder: (context, index, animation) {
              return SizeTransition(
                sizeFactor: animation,
                child: FadeTransition(
                  opacity: animation,
                  child: ScaleTransition(
                    scale: animation,
                    child:
                        _buildItem(context, index, listData[index], animation),
                  ),
                ),
              );
            },
          ),
        ),
        FilledButton(
            onPressed: () {
              listData.add("item ${_nameIndex++}");
              globalListKey.currentState?.insertItem(listData.length - 1);
            },
            child: const Text("add item"))
      ],
    );
  }

  Widget _buildItem(BuildContext context, int? index, String item,
      Animation<double> animation) {
    final colorScheme = Theme.of(context).colorScheme;
    return InkWell(
      onTap: () {
        if (index != null) {
          final removedItem = listData.removeAt(index);
          globalListKey.currentState?.removeItem(index, (context, animation) {
            return FadeTransition(
              opacity: animation,
              child: ScaleTransition(
                  scale: animation,
                  child: _buildItem(context, null, removedItem, animation)),
            );
          });
        }
      },
      child: Container(
        width: double.infinity,
        decoration: BoxDecoration(
          color: colorScheme.primary,
          borderRadius: M3.connerRadiusMedium,
        ),
        padding: const EdgeInsetsDirectional.symmetric(horizontal: M3.paddingM),
        alignment: AlignmentDirectional.center,
        child: Text(
          item,
          style: TextStyle(color: colorScheme.onPrimary),
        ),
      ),
    );
  }
}
